// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.network;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashSet;
import se.krka.kahlua.j2se.KahluaTableImpl;
import se.krka.kahlua.vm.KahluaTable;
import se.krka.kahlua.vm.KahluaTableIterator;
import zombie.Lua.LuaManager;
import zombie.inventory.InventoryItem;
import zombie.iso.IsoDirections;

public final class TableNetworkUtils {
    private static final byte SBYT_NO_SAVE = -1;
    private static final byte SBYT_STRING = 0;
    private static final byte SBYT_DOUBLE = 1;
    private static final byte SBYT_TABLE = 2;
    private static final byte SBYT_BOOLEAN = 3;
    private static final byte SBYT_ITEM = 4;
    private static final byte SBYT_DIRECTION = 5;

    public static void save(KahluaTable kahluaTable, ByteBuffer byteBuffer) throws IOException {
        KahluaTableIterator kahluaTableIterator = kahluaTable.iterator();
        int _int = 0;

        while (kahluaTableIterator.advance()) {
            if (canSave(kahluaTableIterator.getKey(), kahluaTableIterator.getValue())) {
                _int++;
            }
        }

        kahluaTableIterator = kahluaTable.iterator();
        byteBuffer.putInt(_int);

        while (kahluaTableIterator.advance()) {
            byte byte0 = getKeyByte(kahluaTableIterator.getKey());
            byte byte1 = getValueByte(kahluaTableIterator.getValue());
            if (byte0 != -1 && byte1 != -1) {
                save(byteBuffer, byte0, kahluaTableIterator.getKey());
                save(byteBuffer, byte1, kahluaTableIterator.getValue());
            }
        }
    }

    public static void saveSome(KahluaTable kahluaTable, ByteBuffer byteBuffer, HashSet<? extends Object> hashSet) throws IOException {
        KahluaTableIterator kahluaTableIterator = kahluaTable.iterator();
        int _int = 0;

        while (kahluaTableIterator.advance()) {
            if (hashSet.contains(kahluaTableIterator.getKey()) && canSave(kahluaTableIterator.getKey(), kahluaTableIterator.getValue())) {
                _int++;
            }
        }

        kahluaTableIterator = kahluaTable.iterator();
        byteBuffer.putInt(_int);

        while (kahluaTableIterator.advance()) {
            if (hashSet.contains(kahluaTableIterator.getKey())) {
                byte byte0 = getKeyByte(kahluaTableIterator.getKey());
                byte byte1 = getValueByte(kahluaTableIterator.getValue());
                if (byte0 != -1 && byte1 != -1) {
                    save(byteBuffer, byte0, kahluaTableIterator.getKey());
                    save(byteBuffer, byte1, kahluaTableIterator.getValue());
                }
            }
        }
    }

    private static void save(ByteBuffer byteBuffer, byte _byte, Object object) throws IOException, RuntimeException {
        byteBuffer.put(_byte);
        if (_byte == 0) {
            zombie.GameWindow.WriteString(byteBuffer, (String)object);
        } else if (_byte == 1) {
            byteBuffer.putDouble((Double)object);
        } else if (_byte == 3) {
            byteBuffer.put((byte)((Boolean)object ? 1 : 0));
        } else if (_byte == 2) {
            save((KahluaTable)object, byteBuffer);
        } else if (_byte == 4) {
            ((InventoryItem)object).saveWithSize(byteBuffer, false);
        } else {
            if (_byte != 5) {
                throw new RuntimeException("invalid lua table type " + _byte);
            }

            byteBuffer.put((byte)((IsoDirections)object).index());
        }
    }

    public static void load(KahluaTable kahluaTable, ByteBuffer byteBuffer) throws IOException {
        int int0 = byteBuffer.getInt();
        kahluaTable.wipe();

        for (int int1 = 0; int1 < int0; int1++) {
            byte byte0 = byteBuffer.get();
            Object object0 = load(byteBuffer, byte0);
            byte byte1 = byteBuffer.get();
            Object object1 = load(byteBuffer, byte1);
            kahluaTable.rawset(object0, object1);
        }
    }

    public static Object load(ByteBuffer input, byte sbyt) throws IOException, RuntimeException {
        if (sbyt == 0) {
            return zombie.GameWindow.ReadString(input);
        } else if (sbyt == 1) {
            return input.getDouble();
        } else if (sbyt == 3) {
            return input.get() == 1;
        } else if (sbyt == 2) {
            KahluaTableImpl kahluaTableImpl = (KahluaTableImpl)LuaManager.platform.newTable();
            load(kahluaTableImpl, input);
            return kahluaTableImpl;
        } else if (sbyt == 4) {
            InventoryItem inventoryItem = null;

            try {
                inventoryItem = InventoryItem.loadItem(input, 195);
            } catch (Exception exception) {
                exception.printStackTrace();
            }

            return inventoryItem;
        } else if (sbyt == 5) {
            return IsoDirections.fromIndex(input.get());
        } else {
            throw new RuntimeException("invalid lua table type " + sbyt);
        }
    }

    private static byte getKeyByte(Object object) {
        if (object instanceof String) {
            return 0;
        } else {
            return (byte)(object instanceof Double ? 1 : -1);
        }
    }

    private static byte getValueByte(Object object) {
        if (object instanceof String) {
            return 0;
        } else if (object instanceof Double) {
            return 1;
        } else if (object instanceof Boolean) {
            return 3;
        } else if (object instanceof KahluaTableImpl) {
            return 2;
        } else if (object instanceof InventoryItem) {
            return 4;
        } else {
            return (byte)(object instanceof IsoDirections ? 5 : -1);
        }
    }

    public static boolean canSave(Object key, Object value) {
        return getKeyByte(key) != -1 && getValueByte(value) != -1;
    }
}
